package com.itcam.daijia.order.service.impl;

import com.itcam.daijia.common.constant.RedisConstant;
import com.itcam.daijia.common.constant.SystemConstant;
import com.itcam.daijia.common.execption.NGException;
import com.itcam.daijia.common.result.ResultCodeEnum;
import com.itcam.daijia.map.client.MapFeignClient;
import com.itcam.daijia.model.entity.order.*;
import com.itcam.daijia.model.enums.OrderStatus;
import com.itcam.daijia.model.form.customer.SubmitOrderForm;
import com.itcam.daijia.model.form.map.CalculateDrivingLineForm;
import com.itcam.daijia.model.form.order.OrderInfoForm;
import com.itcam.daijia.model.form.order.StartDriveForm;
import com.itcam.daijia.model.form.order.UpdateOrderBillForm;
import com.itcam.daijia.model.form.order.UpdateOrderCartForm;
import com.itcam.daijia.model.form.rules.FeeRuleRequest;
import com.itcam.daijia.model.form.rules.FeeRuleRequestForm;
import com.itcam.daijia.model.vo.base.PageVo;
import com.itcam.daijia.model.vo.map.DrivingLineVo;
import com.itcam.daijia.model.vo.order.*;
import com.itcam.daijia.model.vo.rules.FeeRuleResponse;
import com.itcam.daijia.model.vo.rules.FeeRuleResponseVo;
import com.itcam.daijia.order.client.OrderInfoFeignClient;
import com.itcam.daijia.order.controller.OrderInfoController;
import com.itcam.daijia.order.mapper.OrderBillMapper;
import com.itcam.daijia.order.mapper.OrderInfoMapper;
import com.itcam.daijia.order.mapper.OrderProfitsharingMapper;
import com.itcam.daijia.order.mapper.OrderStatusLogMapper;
import com.itcam.daijia.order.service.OrderInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itcam.daijia.order.service.OrderMonitorService;
import com.itcam.daijia.rules.client.FeeRuleFeignClient;
import org.redisson.api.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderStatusLogMapper orderStatusLogMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private OrderMonitorService orderMonitorService;

    @Autowired
    private MapFeignClient mapFeignClient;

    @Autowired
    private FeeRuleFeignClient feeRuleFeignClient;

    @Autowired
    private OrderInfoController orderInfoController;

    @Autowired
    private OrderInfoFeignClient orderInfoFeignClient;

    @Autowired
    private OrderBillMapper orderBillMapper;

    @Autowired
    private OrderProfitsharingMapper orderProfitsharingMapper;
    private OrderBillVo orderBillVo;
    private OrderBillVo orderBillVo1;

    /**
     * 保存订单信息
     *
     * @param orderInfoForm 订单信息表单
     * @return 订单ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrderInfo(OrderInfoForm orderInfoForm) {
        // 创建一个新的OrderInfo对象
        OrderInfo orderInfo = new OrderInfo();
        // 将orderInfoForm中的属性复制到orderInfo中
        BeanUtils.copyProperties(orderInfoForm, orderInfo);
        // 生成一个随机的订单号
        String orderNo = UUID.randomUUID().toString().replaceAll("-", "");
        // 设置订单状态为等待接单
        orderInfo.setStatus(OrderStatus.WAITING_ACCEPT.getStatus());
        // 设置订单号
        orderInfo.setOrderNo(orderNo);
        // 将订单信息插入数据库
        orderInfoMapper.insert(orderInfo);

        // 记录日志
        this.log(orderInfo.getId(), orderInfo.getStatus());

        // 接单标识，标识不存在了说明再等待接单状态了
        redisTemplate.opsForValue().set(RedisConstant.ORDER_ACCEPT_MARK, "0", RedisConstant.ORDER_ACCEPT_MARK_EXPIRES_TIME, TimeUnit.MINUTES);

        // 返回订单ID
        return orderInfo.getId();
    }

    /**
     * 根据订单id获取订单状态
     * @param orderId 订单id
     * @return 订单状态
     */
    @Override
    public Integer getOrderStatus(Long orderId) {
        // 创建一个LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        // 添加查询条件，订单id等于传入的orderId
        queryWrapper.eq(OrderInfo::getId, orderId);
        // 指定查询结果只包含订单状态字段
        queryWrapper.select(OrderInfo::getStatus);
        // 调用orderInfoMapper的selectOne方法，根据查询条件查询订单信息
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        // 如果订单信息为空，则返回默认的订单状态
        if (null == orderInfo) {
            // 返回null，feign解析会抛出异常，给默认值，后续会用
            return OrderStatus.NULL_ORDER.getStatus();
        }
        // 返回查询到的订单状态
        return orderInfo.getStatus();
    }

    /**
     * 司机抢单
     * @param driverId
     * @param orderId
     * @return
     */
    @Override
    public Boolean robNewOrder(Long driverId, Long orderId) {
        // 抢单成功或取消订单，都会删除该key，redis判断，减少数据库压力
        if (redisTemplate.hasKey(RedisConstant.ORDER_ACCEPT_MARK)) {
            // 抢单失败
            throw new NGException(ResultCodeEnum.COB_NEW_ORDER_FAIL);
        }

//        // 修改订单状态及司机id
//        // update order_info set status = 2,driver_id = #{driver_id},accept_time = now() where id = #{id}
//        // 修改字段
//        OrderInfo orderInfo = new OrderInfo();
//        orderInfo.setId(orderId);
//        orderInfo.setStatus(OrderStatus.ACCEPTED.getStatus());
//        orderInfo.setAcceptTime(new Date());
//        orderInfo.setDriverId(driverId);
//        int rows = orderInfoMapper.updateById(orderInfo);
//        if (rows != 1) {
//            // 抢单失败
//            throw new NGException(ResultCodeEnum.COB_NEW_ORDER_FAIL);
//        }
//
//        // 记录日志
//        this.log(orderId, orderInfo.getStatus());
//
//        // 删除redis订单框架
//        redisTemplate.delete(RedisConstant.ORDER_ACCEPT_MARK);

        // 初始化分布式锁，创建一个RLock实例
        RLock lock = redissonClient.getLock(RedisConstant.ROB_NEW_ORDER_LOCK + orderId);
        try {
            /**
             * TryLock是一种非阻塞式的分布式锁，实现原理：Redis的SETNX命令
             * 参数：
             *     waitTime：等待获取锁的时间
             *     leaseTime：加锁的时间
             */
            boolean flag = lock.tryLock(RedisConstant.ROB_NEW_ORDER_LOCK_WAIT_TIME, RedisConstant.ROB_NEW_ORDER_LOCK_LEASE_TIME, TimeUnit.SECONDS);
            //获取到锁
            if (flag) {
                //二次判断，防止重复抢单
                if (!redisTemplate.hasKey(RedisConstant.ORDER_ACCEPT_MARK)) {
                    //抢单失败
                    throw new NGException(ResultCodeEnum.COB_NEW_ORDER_FAIL);
                }

                //修改订单状态
                //update order_info set status = 2, driver_id = #{driverId} where id = #{id}
                //修改字段
                OrderInfo orderInfo = new OrderInfo();
                orderInfo.setId(orderId);
                orderInfo.setStatus(OrderStatus.ACCEPTED.getStatus());
                orderInfo.setAcceptTime(new Date());
                orderInfo.setDriverId(driverId);
                int rows = orderInfoMapper.updateById(orderInfo);
                if (rows != 1) {
                    //抢单失败
                    throw new NGException(ResultCodeEnum.COB_NEW_ORDER_FAIL);
                }

                //记录日志
                this.log(orderId, orderInfo.getStatus());

                //删除redis订单标识
                redisTemplate.delete(RedisConstant.ORDER_ACCEPT_MARK);
            }
        } catch (InterruptedException e) {
            //抢单失败
            throw new NGException(ResultCodeEnum.COB_NEW_ORDER_FAIL);
        } finally {
            if (lock.isLocked()) {
                lock.unlock();
            }
        }
        return true;
    }

    /**
     * 乘客端查找当前订单
     * @param customerId 乘客ID
     * @return 当前订单信息
     */
    @Override
    public CurrentOrderInfoVo searchCustomerCurrentOrder(Long customerId) {
        // 创建一个LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        // 添加查询条件，乘客id等于传入的customerId
        queryWrapper.eq(OrderInfo::getCustomerId, customerId);
        // 乘客端支付完订单，乘客端主要流程就走完了（当前这些节点，乘客端回调整到相应的页面处理逻辑）
        Integer[] statusArray = {
                OrderStatus.ACCEPTED.getStatus(), // 已接单
                OrderStatus.DRIVER_ARRIVED.getStatus(), // 司机已到达
                OrderStatus.UPDATE_CART_INFO.getStatus(), // 更新代价车辆信息
                OrderStatus.START_SERVICE.getStatus(), // 开始服务
                OrderStatus.END_SERVICE.getStatus(), // 结束服务
                OrderStatus.UNPAID.getStatus() // 待付款
        };
        // 添加查询条件，订单状态在statusArray数组中
        queryWrapper.in(OrderInfo::getStatus, statusArray);
        // 按照订单id降序排列
        queryWrapper.orderByDesc(OrderInfo::getId);
        // 查询结果限制为1条
        queryWrapper.last("limit 1");
        // 调用orderInfoMapper的selectOne方法，根据查询条件查询订单信息
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        // 创建一个CurrentOrderInfoVo对象，用于封装查询结果
        CurrentOrderInfoVo currentOrderInfoVo = new CurrentOrderInfoVo();
        // 如果订单信息不为空，则设置当前订单信息
        if (null != orderInfo) {
            currentOrderInfoVo.setStatus(orderInfo.getStatus());
            currentOrderInfoVo.setOrderId(orderInfo.getId());
            currentOrderInfoVo.setIsHasCurrentOrder(true);
        } else {
            // 如果订单信息为空，则设置当前订单不存在
            currentOrderInfoVo.setIsHasCurrentOrder(false);
        }
        // 返回当前订单信息
        return currentOrderInfoVo;
    }

    /**
     * 司机端查找当前订单
     * @param driverId 司机ID
     * @return 当前订单信息
     */
    @Override
    public CurrentOrderInfoVo searchDriverCurrentOrder(Long driverId) {
        // 创建一个LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        // 添加查询条件，司机id等于传入的driverId
        queryWrapper.eq(OrderInfo::getDriverId, driverId);
        // 司机发送完账单，司机端主要流程（当前这些节点，司机端会调整到相应的页面处理逻辑）
        Integer[] statusArray = {
                OrderStatus.ACCEPTED.getStatus(), // 已接单
                OrderStatus.UPDATE_CART_INFO.getStatus(), // 更新代价车辆信息
                OrderStatus.START_SERVICE.getStatus(), // 开始服务
                OrderStatus.END_SERVICE.getStatus(), // 结束服务
                OrderStatus.UNPAID.getStatus() // 待付款
        };
        // 添加查询条件，订单状态在statusArray数组中
        queryWrapper.in(OrderInfo::getStatus, statusArray);
        // 按照订单id降序排列
        queryWrapper.orderByDesc(OrderInfo::getId);
        // 查询结果限制为1条
        queryWrapper.last("limit 1");
        // 调用orderInfoMapper的selectOne方法，根据查询条件查询订单信息
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        // 创建一个CurrentOrderInfoVo对象，用于封装查询结果
        CurrentOrderInfoVo currentOrderInfoVo = new CurrentOrderInfoVo();
        // 如果订单信息不为空，则设置当前订单信息
        if (null != orderInfo) {
            currentOrderInfoVo.setStatus(orderInfo.getStatus());
            currentOrderInfoVo.setOrderId(orderInfo.getId());
            currentOrderInfoVo.setIsHasCurrentOrder(true);
        } else {
            // 如果订单信息为空，则设置当前订单不存在
            currentOrderInfoVo.setIsHasCurrentOrder(false);
        }
        // 返回当前订单信息
        return currentOrderInfoVo;
    }

    /**
     * 司机到达起始点
     * @param orderId
     * @param driverId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean driverArriveStartLocation(Long orderId, Long driverId) {
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderInfo::getId, orderId);
        queryWrapper.eq(OrderInfo::getDriverId, driverId);

        OrderInfo updateOrderInfo = new OrderInfo();
        updateOrderInfo.setStatus(OrderStatus.DRIVER_ARRIVED.getStatus());
        updateOrderInfo.setArriveTime(new Date());
        // 只能更新自己的订单
        int row = orderInfoMapper.update(updateOrderInfo, queryWrapper);
        if (row == 1) {
            // 记录日志
            this.log(orderId, OrderStatus.DRIVER_ARRIVED.getStatus());
        } else {
            throw new NGException(ResultCodeEnum.UPDATE_ERROR);
        }
        return null;
    }

    /**
     * 更新代驾车辆信息
     * @param updateOrderCartForm
     * @return
     */

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateOrderCart(UpdateOrderCartForm updateOrderCartForm) {
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderInfo::getId, updateOrderCartForm.getOrderId());
        queryWrapper.eq(OrderInfo::getDriverId, updateOrderCartForm.getDriverId());

        OrderInfo updateOrderInfo = new OrderInfo();
        BeanUtils.copyProperties(updateOrderCartForm, updateOrderInfo);
        updateOrderInfo.setStatus(OrderStatus.UPDATE_CART_INFO.getStatus());
        // 只能更新自己的订单
        int row = orderInfoMapper.update(updateOrderInfo, queryWrapper);
        if (row == 1) {
            // 记录日志
            this.log(updateOrderCartForm.getOrderId(), OrderStatus.UPDATE_CART_INFO.getStatus());
        } else {
            throw new NGException(ResultCodeEnum.UPDATE_ERROR);
        }
        return null;
    }

    /**
     * 开始代驾服务
     * @param startDriveForm 开始代驾表单
     * @return 是否开始代驾服务成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean startDrive(StartDriveForm startDriveForm) {
        // 创建一个LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        // 添加查询条件，订单id等于传入的startDriveForm中的订单id
        queryWrapper.eq(OrderInfo::getId, startDriveForm.getOrderId());
        // 添加查询条件，司机id等于传入的startDriveForm中的司机id
        queryWrapper.eq(OrderInfo::getDriverId, startDriveForm.getDriverId());

        // 创建一个OrderInfo对象，用于更新数据库中的数据
        OrderInfo updateOrderInfo = new OrderInfo();
        // 设置订单状态为开始服务状态
        updateOrderInfo.setStatus(OrderStatus.START_SERVICE.getStatus());
        // 设置开始服务时间为当前时间
        updateOrderInfo.setStartServiceTime(new Date());

        // 只能更新自己的订单
        // 调用orderInfoMapper的update方法，根据查询条件更新订单信息
        int row = orderInfoMapper.update(updateOrderInfo, queryWrapper);
        // 如果更新成功，则记录日志
        if (row == 1) {
            // 记录日志
            this.log(startDriveForm.getOrderId(), OrderStatus.START_SERVICE.getStatus());
        } else {
            // 如果更新失败，则抛出更新错误异常
            throw new NGException(ResultCodeEnum.UPDATE_ERROR);
        }
        //初始化订单监控统计数据
        OrderMonitor orderMonitor = new OrderMonitor();
        orderMonitor.setOrderId(startDriveForm.getOrderId());
        orderMonitorService.saveOrderMonitor(orderMonitor);
        // 返回true表示开始代驾服务成功
        return true;
    }

    /**
     * 根据时间段获取订单数
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public Long getOrderNumByTime(String startTime, String endTime) {
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(OrderInfo::getStartServiceTime, startTime);
        queryWrapper.lt(OrderInfo::getEndServiceTime, endTime);
        Long count = orderInfoMapper.selectCount(queryWrapper);
        return count;
    }

    /**
     * 结束代驾服务更新订单账单
     * @param updateOrderBillForm
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean endDrive(UpdateOrderBillForm updateOrderBillForm) {
        //更新订单信息
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderInfo::getId, updateOrderBillForm.getOrderId());
        queryWrapper.eq(OrderInfo::getDriverId, updateOrderBillForm.getDriverId());
        //更新字段
        OrderInfo updateOrderInfo = new OrderInfo();
        updateOrderInfo.setStatus(OrderStatus.END_SERVICE.getStatus());
        updateOrderInfo.setRealAmount(updateOrderBillForm.getTotalAmount());
        updateOrderInfo.setFavourFee(updateOrderBillForm.getFavourFee());
        updateOrderInfo.setEndServiceTime(new Date());
        updateOrderInfo.setRealDistance(updateOrderBillForm.getRealDistance());
        //只能更新自己的订单
        int row = orderInfoMapper.update(updateOrderInfo, queryWrapper);
        if (row == 1) {
            //记录日志
            this.log(updateOrderBillForm.getOrderId(), OrderStatus.END_SERVICE.getStatus());

            //插入实际账单数据
            OrderBill orderBill = new OrderBill();
            BeanUtils.copyProperties(updateOrderBillForm, orderBill);
            orderBill.setOrderId(updateOrderBillForm.getOrderId());
            orderBill.setPayAmount(orderBill.getTotalAmount());
            orderBillMapper.insert(orderBill);

            //插入分账信息数据
            OrderProfitsharing orderProfitsharing = new OrderProfitsharing();
            BeanUtils.copyProperties(updateOrderBillForm, orderProfitsharing);
            orderProfitsharing.setOrderId(updateOrderBillForm.getOrderId());
            orderProfitsharing.setRuleId(updateOrderBillForm.getProfitsharingRuleId());
            orderProfitsharing.setStatus(1);
            orderProfitsharingMapper.insert(orderProfitsharing);
        } else {
            throw new NGException(ResultCodeEnum.UPDATE_ERROR);
        }
        return true;
    }

    /**
     * 获取乘客订单分页列表
     * @param pageParam
     * @param customerId
     * @return
     */
    @Override
    public PageVo findCustomerOrderPage(Page<OrderInfo> pageParam, Long customerId) {
        IPage<OrderListVo> pageInfo = orderInfoMapper.selectCustomerOrderPage(pageParam, customerId);
        return new PageVo(pageInfo.getRecords(), pageInfo.getPages(), pageInfo.getTotal());
    }

    /**
     * 获取司机订单分页列表
     * @param pageParam
     * @param driverId
     * @return
     */
    @Override
    public PageVo findDriverOrderPage(Page<OrderInfo> pageParam, Long driverId) {
        IPage<OrderListVo> pageInfo = orderInfoMapper.selectDriverOrderPage(pageParam, driverId);
        return new PageVo(pageInfo.getRecords(), pageInfo.getPages(), pageInfo.getTotal());
    }

    /**
     * 根据订单id获取实际账单信息
     * @param orderId 订单id
     * @return 订单账单信息
     */
    @Override
    public OrderBillVo getOrderBillInfo(Long orderId) {
        // 根据订单id查询订单账单信息
        OrderBill orderBill = orderBillMapper.selectOne(new LambdaQueryWrapper<OrderBill>().eq(OrderBill::getOrderId, orderId));
        // 创建一个订单账单信息对象
        OrderBillVo orderBillVo1 = new OrderBillVo();
        // 将查询到的订单账单信息复制到订单账单信息对象中
        BeanUtils.copyProperties(orderBill, orderBillVo1);
        // 返回订单账单信息对象
        return orderBillVo1;
    }

    /**
     * 根据订单id获取实际分账信息
     *
     * @param orderId 订单id
     * @return 返回分账信息
     */
    @Override
    public OrderProfitsharingVo getOrderProfitsharing(Long orderId) {
        // 根据订单id查询分账信息
        OrderProfitsharing orderProfitsharing = orderProfitsharingMapper.selectOne(new LambdaQueryWrapper<OrderProfitsharing>()
                // 条件：订单id等于传入的orderId
                .eq(OrderProfitsharing::getOrderId, orderId));
        // 创建一个分账信息对象
        OrderProfitsharingVo orderProfitsharingVo = new OrderProfitsharingVo();
        // 将查询到的分账信息复制到分账信息对象中
        BeanUtils.copyProperties(orderProfitsharing, orderProfitsharingVo);
        // 返回分账信息对象
        return orderProfitsharingVo;
    }

    /**
     * 发送账单信息
     * @param orderId 订单id
     * @param driverId 司机id
     * @return 返回是否发送成功
     */
    @Override
    public Boolean sendOrderBillInfo(Long orderId, Long driverId) {
        // 更新订单信息
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderInfo::getId, orderId);
        queryWrapper.eq(OrderInfo::getDriverId, driverId);
        // 更新字段
        OrderInfo updateOrderInfo = new OrderInfo();
        updateOrderInfo.setStatus(OrderStatus.UNPAID.getStatus());
        // 只能更新自己的订单
        int row = orderInfoMapper.update(updateOrderInfo, queryWrapper);
        if (row == 1) {
            // 记录日志
            this.log(orderId, OrderStatus.UNPAID.getStatus());
        } else {
            throw new NGException(ResultCodeEnum.UPDATE_ERROR);
        }
        return true;
    }

    /**
     * 获取订单支付信息
     * @param orderNo
     * @param customerId
     * @return
     */
    @Override
    public OrderPayVo getOrderPayVo(String orderNo, Long customerId) {
        OrderPayVo orderPayVo = orderInfoMapper.selectOrderPayVo(orderNo, customerId);
        if (null != orderPayVo) {
            String content = orderPayVo.getStartLocation() + " 到 " + orderPayVo.getEndLocation();
            orderPayVo.setContent(content);
        }
        return orderPayVo;
    }

    /**
     * 更新订单优惠券金额
     * @param orderId
     * @param couponAmount
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateCouponAmount(Long orderId, BigDecimal couponAmount) {
        int row = orderBillMapper.updateCouponAmount(orderId, couponAmount);
        if (row != 1) {
            throw new NGException(ResultCodeEnum.UPDATE_ERROR);
        }
        return true;
    }

    /**
     * 更改订单支付状态
     * @param orderNo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateOrderPayStatus(String orderNo) {
        //查询订单，判断订单状态，如果已更新支付状态，直接返回
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderInfo::getOrderNo, orderNo);
        queryWrapper.select(OrderInfo::getId, OrderInfo::getDriverId, OrderInfo::getStatus);
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        if (null == orderInfo || orderInfo.getStatus().intValue() == OrderStatus.PAID.getStatus().intValue())
            return true;

        //更新订单状态
        LambdaQueryWrapper<OrderInfo> updateQueryWrapper = new LambdaQueryWrapper<>();
        updateQueryWrapper.eq(OrderInfo::getOrderNo, orderNo);

        //更新字段
        OrderInfo updateOrderInfo = new OrderInfo();
        updateOrderInfo.setStatus(OrderStatus.PAID.getStatus());
        updateOrderInfo.setPayTime(new Date());
        int row = orderInfoMapper.update(updateOrderInfo, queryWrapper);

        if (row == 1) {
            //记录日志
            this.log(orderInfo.getId(), OrderStatus.PAID.getStatus());
        } else {
            log.error("订单支付回调更新订单状态失败，订单号为：" + orderNo);
            throw new NGException(ResultCodeEnum.UPDATE_ERROR);
        }
        return true;
    }

    /**
     * 获取订单的系统奖励
     * @param orderNo
     * @return
     */
    @Override
    public OrderRewardVo getOrderRewardFee(String orderNo) {
        //查询订单
        OrderInfo orderInfo = orderInfoMapper.selectOne(
                new LambdaQueryWrapper<OrderInfo>()
                        .eq(OrderInfo::getOrderNo, orderNo)
                        .select(OrderInfo::getId, OrderInfo::getDriverId));
        //账单
        OrderBill orderBill = orderBillMapper.selectOne(new LambdaQueryWrapper<OrderBill>().eq(OrderBill::getOrderId, orderInfo.getId()).select(OrderBill::getRewardFee));
        OrderRewardVo orderRewardVo = new OrderRewardVo();
        orderRewardVo.setOrderId(orderInfo.getId());
        orderRewardVo.setDriverId(orderInfo.getDriverId());
        orderRewardVo.setRewardFee(orderBill.getRewardFee());
        return orderRewardVo;
    }


    // ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

    /**
     * 记录日志
     * @param orderId
     * @param status
     */
    private void log(Long orderId, Integer status) {
        OrderStatusLog orderStatusLog = new OrderStatusLog();
        orderStatusLog.setOrderId(orderId);
        orderStatusLog.setOrderStatus(status);
        orderStatusLog.setOperateTime(new Date());
        orderStatusLogMapper.insert(orderStatusLog);
    }
}